/**
 * 表单验证工具类
 */

export interface ValidationRule {
  required?: boolean
  min?: number
  max?: number
  pattern?: RegExp
  validator?: (value: any) => boolean | string
  message?: string
}

export interface ValidationResult {
  valid: boolean
  errors: string[]
}

export class FormValidator {
  private rules: Record<string, ValidationRule[]> = {}

  /**
   * 添加字段验证规则
   */
  addRule(field: string, rule: ValidationRule): FormValidator {
    if (!this.rules[field]) {
      this.rules[field] = []
    }
    this.rules[field].push(rule)
    return this
  }

  /**
   * 添加多个字段验证规则
   */
  addRules(rules: Record<string, ValidationRule[]>): FormValidator {
    Object.keys(rules).forEach(field => {
      rules[field].forEach(rule => {
        this.addRule(field, rule)
      })
    })
    return this
  }

  /**
   * 验证单个字段
   */
  validateField(field: string, value: any): ValidationResult {
    const fieldRules = this.rules[field] || []
    const errors: string[] = []

    for (const rule of fieldRules) {
      // 必填验证
      if (rule.required && (value === null || value === undefined || value === '')) {
        errors.push(rule.message || `${field}是必填项`)
        continue
      }

      // 如果值为空且不是必填，跳过其他验证
      if (!rule.required && (value === null || value === undefined || value === '')) {
        continue
      }

      // 最小长度/值验证
      if (rule.min !== undefined) {
        if (typeof value === 'string' && value.length < rule.min) {
          errors.push(rule.message || `${field}最少需要${rule.min}个字符`)
        } else if (typeof value === 'number' && value < rule.min) {
          errors.push(rule.message || `${field}最小值为${rule.min}`)
        }
      }

      // 最大长度/值验证
      if (rule.max !== undefined) {
        if (typeof value === 'string' && value.length > rule.max) {
          errors.push(rule.message || `${field}最多允许${rule.max}个字符`)
        } else if (typeof value === 'number' && value > rule.max) {
          errors.push(rule.message || `${field}最大值为${rule.max}`)
        }
      }

      // 正则表达式验证
      if (rule.pattern && typeof value === 'string' && !rule.pattern.test(value)) {
        errors.push(rule.message || `${field}格式不正确`)
      }

      // 自定义验证器
      if (rule.validator) {
        const result = rule.validator(value)
        if (result !== true) {
          errors.push(typeof result === 'string' ? result : (rule.message || `${field}验证失败`))
        }
      }
    }

    return {
      valid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证整个表单
   */
  validate(data: Record<string, any>): ValidationResult {
    const allErrors: string[] = []

    Object.keys(this.rules).forEach(field => {
      const fieldResult = this.validateField(field, data[field])
      allErrors.push(...fieldResult.errors)
    })

    return {
      valid: allErrors.length === 0,
      errors: allErrors
    }
  }

  /**
   * 清空验证规则
   */
  clear(): FormValidator {
    this.rules = {}
    return this
  }
}

/**
 * 预定义的验证规则
 */
export const ValidationRules = {
  // 必填
  required: (message?: string): ValidationRule => ({
    required: true,
    message: message || '此字段为必填项'
  }),

  // 邮箱
  email: (message?: string): ValidationRule => ({
    pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
    message: message || '请输入有效的邮箱地址'
  }),

  // 手机号
  phone: (message?: string): ValidationRule => ({
    pattern: /^1[3-9]\d{9}$/,
    message: message || '请输入有效的手机号码'
  }),

  // 长度范围
  length: (min: number, max: number, message?: string): ValidationRule => ({
    min,
    max,
    message: message || `长度应在${min}-${max}个字符之间`
  }),

  // 最小长度
  minLength: (min: number, message?: string): ValidationRule => ({
    min,
    message: message || `最少需要${min}个字符`
  }),

  // 最大长度
  maxLength: (max: number, message?: string): ValidationRule => ({
    max,
    message: message || `最多允许${max}个字符`
  }),

  // 数值范围
  range: (min: number, max: number, message?: string): ValidationRule => ({
    min,
    max,
    message: message || `值应在${min}-${max}之间`
  }),

  // 正整数
  positiveInteger: (message?: string): ValidationRule => ({
    validator: (value: any) => {
      const num = Number(value)
      return Number.isInteger(num) && num > 0
    },
    message: message || '请输入正整数'
  }),

  // 非负数
  nonNegative: (message?: string): ValidationRule => ({
    validator: (value: any) => {
      const num = Number(value)
      return !isNaN(num) && num >= 0
    },
    message: message || '请输入非负数'
  }),

  // URL
  url: (message?: string): ValidationRule => ({
    pattern: /^https?:\/\/.+/,
    message: message || '请输入有效的URL地址'
  }),

  // 自定义验证器
  custom: (validator: (value: any) => boolean | string, message?: string): ValidationRule => ({
    validator,
    message
  })
}

/**
 * 工作项验证器工厂
 */
export class WorkItemValidatorFactory {
  /**
   * 创建需求验证器
   */
  static createRequirementValidator(): FormValidator {
    return new FormValidator().addRules({
      title: [
        ValidationRules.required('需求标题不能为空'),
        ValidationRules.length(1, 200, '需求标题长度应在1-200个字符之间')
      ],
      description: [
        ValidationRules.required('需求描述不能为空'),
        ValidationRules.minLength(10, '需求描述至少需要10个字符')
      ],
      type: [
        ValidationRules.required('需求类型不能为空')
      ],
      priority: [
        ValidationRules.required('优先级不能为空')
      ],
      business_value: [
        ValidationRules.range(1, 10, '业务价值应在1-10之间')
      ],
      acceptance_criteria: [
        ValidationRules.required('验收标准不能为空'),
        ValidationRules.minLength(10, '验收标准至少需要10个字符')
      ]
    })
  }

  /**
   * 创建任务验证器
   */
  static createTaskValidator(): FormValidator {
    return new FormValidator().addRules({
      title: [
        ValidationRules.required('任务标题不能为空'),
        ValidationRules.length(1, 200, '任务标题长度应在1-200个字符之间')
      ],
      description: [
        ValidationRules.required('任务描述不能为空'),
        ValidationRules.minLength(5, '任务描述至少需要5个字符')
      ],
      task_type: [
        ValidationRules.required('任务类型不能为空')
      ],
      priority: [
        ValidationRules.required('优先级不能为空')
      ],
      estimated_hours: [
        ValidationRules.nonNegative('预估工时必须为非负数')
      ],
      assignee_id: [
        ValidationRules.required('负责人不能为空')
      ]
    })
  }

  /**
   * 创建缺陷验证器
   */
  static createDefectValidator(): FormValidator {
    return new FormValidator().addRules({
      title: [
        ValidationRules.required('缺陷标题不能为空'),
        ValidationRules.length(1, 200, '缺陷标题长度应在1-200个字符之间')
      ],
      description: [
        ValidationRules.required('缺陷描述不能为空'),
        ValidationRules.minLength(10, '缺陷描述至少需要10个字符')
      ],
      type: [
        ValidationRules.required('缺陷类型不能为空')
      ],
      priority: [
        ValidationRules.required('优先级不能为空')
      ],
      severity: [
        ValidationRules.required('严重程度不能为空')
      ],
      source: [
        ValidationRules.required('缺陷来源不能为空')
      ],
      steps_to_reproduce: [
        ValidationRules.required('复现步骤不能为空'),
        ValidationRules.minLength(10, '复现步骤至少需要10个字符')
      ],
      expected_result: [
        ValidationRules.required('预期结果不能为空')
      ],
      actual_result: [
        ValidationRules.required('实际结果不能为空')
      ]
    })
  }
}

/**
 * 批量操作验证器
 */
export class BatchOperationValidator {
  /**
   * 验证批量分配
   */
  static validateBatchAssign(selectedItems: any[], assigneeId: string): ValidationResult {
    const errors: string[] = []

    if (!selectedItems || selectedItems.length === 0) {
      errors.push('请选择要分配的工作项')
    }

    if (!assigneeId) {
      errors.push('请选择负责人')
    }

    return {
      valid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证批量状态变更
   */
  static validateBatchStatusChange(selectedItems: any[], newStatus: string): ValidationResult {
    const errors: string[] = []

    if (!selectedItems || selectedItems.length === 0) {
      errors.push('请选择要变更状态的工作项')
    }

    if (!newStatus) {
      errors.push('请选择新状态')
    }

    // 检查是否所有工作项都可以变更到目标状态
    const invalidItems = selectedItems.filter(item => {
      // 这里可以添加更复杂的状态转换验证逻辑
      return item.status === newStatus
    })

    if (invalidItems.length > 0) {
      errors.push(`有${invalidItems.length}个工作项已经是目标状态`)
    }

    return {
      valid: errors.length === 0,
      errors
    }
  }

  /**
   * 验证批量删除
   */
  static validateBatchDelete(selectedItems: any[]): ValidationResult {
    const errors: string[] = []

    if (!selectedItems || selectedItems.length === 0) {
      errors.push('请选择要删除的工作项')
    }

    // 检查是否有不能删除的工作项（如已完成的工作项）
    const undeletableItems = selectedItems.filter(item => {
      return item.status === 'completed' && item.type === 'requirement'
    })

    if (undeletableItems.length > 0) {
      errors.push(`有${undeletableItems.length}个已完成的需求不能删除`)
    }

    return {
      valid: errors.length === 0,
      errors
    }
  }
}

/**
 * 权限验证器
 */
export class PermissionValidator {
  /**
   * 验证创建权限
   */
  static canCreate(userRole: string, module: string): boolean {
    const permissions: Record<string, string[]> = {
      requirements: ['admin', 'project_manager', 'business_analyst'],
      tasks: ['admin', 'project_manager', 'developer', 'tester'],
      defects: ['admin', 'project_manager', 'developer', 'tester']
    }

    return permissions[module]?.includes(userRole) || false
  }

  /**
   * 验证编辑权限
   */
  static canEdit(userRole: string, workItem: any, currentUserId: string): boolean {
    // 管理员和项目经理可以编辑所有工作项
    if (['admin', 'project_manager'].includes(userRole)) {
      return true
    }

    // 负责人可以编辑自己的工作项
    if (workItem.assignee_id === currentUserId) {
      return true
    }

    // 创建者可以编辑自己创建的工作项
    if (workItem.reporter_id === currentUserId) {
      return true
    }

    return false
  }

  /**
   * 验证删除权限
   */
  static canDelete(userRole: string, workItem: any, currentUserId: string): boolean {
    // 只有管理员和项目经理可以删除工作项
    if (['admin', 'project_manager'].includes(userRole)) {
      return true
    }

    // 创建者可以删除自己创建的未开始工作项
    if (workItem.reporter_id === currentUserId && workItem.status === 'todo') {
      return true
    }

    return false
  }

  /**
   * 验证状态变更权限
   */
  static canChangeStatus(userRole: string, workItem: any, currentUserId: string, newStatus: string): boolean {
    // 管理员和项目经理可以变更任何状态
    if (['admin', 'project_manager'].includes(userRole)) {
      return true
    }

    // 负责人可以变更自己工作项的状态
    if (workItem.assignee_id === currentUserId) {
      return true
    }

    // 特殊状态变更权限
    if (newStatus === 'completed' && workItem.type === 'defect') {
      // 缺陷完成需要测试人员或更高权限
      return ['tester', 'project_manager', 'admin'].includes(userRole)
    }

    return false
  }
}